package cn.wolfcode.business.service.impl;

import java.util.Date;
import java.util.List;

import cn.wolfcode.business.domain.Statement;
import cn.wolfcode.business.mapper.StatementMapper;
import cn.wolfcode.business.util.RegexUtils;
import cn.wolfcode.business.util.VehiclePlateNoUtil;
import cn.wolfcode.common.exception.ServiceException;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.bean.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.mapper.AppointmentMapper;
import cn.wolfcode.business.domain.Appointment;
import cn.wolfcode.business.service.IAppointmentService;
import org.springframework.util.Assert;

/**
 * 养修信息预约Service业务层处理
 * 
 * @author dafei
 * @date 2023-10-28
 */
@Service
public class AppointmentServiceImpl implements IAppointmentService 
{
    @Autowired
    private AppointmentMapper appointmentMapper;
    @Autowired
    private StatementMapper statementMapper;

    /**
     * 查询养修信息预约
     * 
     * @param id 养修信息预约主键
     * @return 养修信息预约
     */
    @Override
    public Appointment selectAppointmentById(Long id)
    {
        return appointmentMapper.selectAppointmentById(id);
    }

    /**
     * 查询养修信息预约列表
     * 
     * @param appointment 养修信息预约
     * @return 养修信息预约
     */
    @Override
    public List<Appointment> selectAppointmentList(Appointment appointment)
    {
        return appointmentMapper.selectAppointmentList(appointment);
    }

    /**
     * 新增养修信息预约
     * 
     * @param appointment 养修信息预约
     * @return 结果
     */
    @Override
    public int insertAppointment(Appointment appointment)
    {
       /* //参数合法性校验
        if(appointment ==  null){
            //throw new RuntimeException("参数异常");
            throw new ServiceException("参数异常");
        }*/


        //断言工具类--我判断xxx, 满足则往下周, 不满足抛异常
        Assert.notNull(appointment, "参数异常");


        //手机号码格式校验
        /*if(!RegexUtils.isPhoneLegal(appointment.getCustomerPhone())){
            throw new ServiceException("手机号码格式不正确");
        }
        */
        Assert.state(RegexUtils.isPhoneLegal(appointment.getCustomerPhone()), "手机号码格式不正确");

        //车牌号码校验
        VehiclePlateNoUtil.VehiclePlateNoEnum vehiclePlateNo = VehiclePlateNoUtil.getVehiclePlateNo(appointment.getLicensePlate());
        Assert.state(vehiclePlateNo != null, "车牌号不正确");
        //预约时间校验
        Date now = new Date();
//        if(appointment.getAppointmentTime().before(now)){
//            throw new ServiceException("预约时间必须在今天之后不正确");
//        }

        Assert.state(!appointment.getAppointmentTime().before(now), "预约时间必须在今天之后不正确");
        //Map--{key value, key value, key value}





        //进行赋值操作---- 讲不需要的属性给排除--copyProperties 方法前提: 属性名一致才进行拷贝---自己思考: 想象传入参数是map接口, 处理是对象
        //Appointment busAppointment1 = new Appointment();
        //BeanUtils.copyProperties(appointment, busAppointment1);
        //appointment.setCreateTime(DateUtils.getNowDate());
        //return appointmentMapper.insertAppointment(busAppointment1);


        appointment.setCreateTime(DateUtils.getNowDate());
        return appointmentMapper.insertAppointment(appointment);
    }

    /**
     * 修改养修信息预约
     * 
     * @param appointment 养修信息预约
     * @return 结果
     */
    @Override
    public int updateAppointment(Appointment appointment)
    {
        //参数合法性校验
        //参数不为空
        //手机号码格式
        //车牌格式
        //预约时间
        Assert.notNull(appointment, "参数异常");
        Assert.state(RegexUtils.isPhoneLegal(appointment.getCustomerPhone()), "手机号码格式不正确");
        //车牌号码校验
        VehiclePlateNoUtil.VehiclePlateNoEnum vehiclePlateNo = VehiclePlateNoUtil.getVehiclePlateNo(appointment.getLicensePlate());
        Assert.state(vehiclePlateNo != null, "车牌号不正确");
        //预约时间校验
        Date now = new Date();
        Assert.state(!appointment.getAppointmentTime().before(now), "预约时间必须在今天之后不正确");

        //必须在允许编辑状态下做修改: 预约中
        //问题: 状态怎么获取问题
        //1 > 直接从传入appointment 参数中获取----页面传入, 有可能被伪装
        //2 > 从数据库中获取--安全
        Appointment app = appointmentMapper.selectAppointmentById(appointment.getId());
        if(!Appointment.STATUS_APPOINTMENT.equals(app.getStatus())){
            throw  new ServiceException("只有在预约状态下才允许修改");
        }
        return appointmentMapper.updateAppointment(appointment);
    }

    /**
     * 批量删除养修信息预约
     * 
     * @param ids 需要删除的养修信息预约主键
     * @return 结果
     */
    @Override
    public int deleteAppointmentByIds(Long[] ids)
    {

        //@todo 实现软删除
        //假删除: 在表中添加新的列: is_del     0:正常  1:删除
        //删除时, 仅仅伤 is_del 状态值改为 1, 后续列表查询时, 额外添加一个条件  where is_del = 0
        //好处: 1>有反悔机会  2>有利维护系统稳定性
        //删除存在2种逻辑

        //真删除:数据库数据被删掉--假删除:数据库数据没有被删,仅仅页面数据不显示
        //硬删除--软删除
        //物理删除--逻辑删除

        //--自己加上状态判断
        return appointmentMapper.deleteAppointmentByIds(ids);
    }

    /**
     * 删除养修信息预约信息
     * 
     * @param id 养修信息预约主键
     * @return 结果
     */
    @Override
    public int deleteAppointmentById(Long id)
    {
        return appointmentMapper.deleteAppointmentById(id);
    }


    @Override
    public void arralShop(Long id) {

        //参数校验-id 不为空同时能查出值来
        Appointment appointment = appointmentMapper.selectAppointmentById(id);
        if(appointment == null){
            throw new ServiceException("参数异常");
        }
        //是否满足到店状态
        if(!Appointment.STATUS_APPOINTMENT.equals(appointment.getStatus())){
            throw new ServiceException("必须是预约状态才可以执行到店逻辑");
        }

        //更新第一钟方式
        //设置到店时间
        appointment.setActualArrivalTime(new Date());
        //修改到店状态
        appointment.setStatus(Appointment.STATUS_ARRIVAL);
        //更新
        appointmentMapper.updateAppointment(appointment);



        //更新第二种方式
        //sql: update bus_appoment set actual_arrival_time = new Date, state =   Appointment.STATUS_ARRIVAL where id = id
        //appointmentMapper.updateArralShop(appointment.getId(), new Date(), Appointment.STATUS_ARRIVAL);
    }

    @Override
    public void cancel(Long id) {
        //参数校验--id 有值, 并且查询对象
        Appointment appointment = appointmentMapper.selectAppointmentById(id);
        if(appointment == null){
            throw new ServiceException("参数异常");
        }
        //判读满足取消操作状态: 预约中
        if(!Appointment.STATUS_APPOINTMENT.equals(appointment.getStatus())){
            throw new ServiceException("必须是预约状态才可以执行取消逻辑");
        }
        //修改状态为: 取消
        //appointment.setStatus(Appointment.STATUS_CANCEL);
        //appointmentMapper.updateAppointment(appointment);

        appointmentMapper.updateStatus(id, Appointment.STATUS_CANCEL);
    }

    @Override
    public Long generate(Long appointmentId) {
        //判断预约单是已到店状态才执行
        Appointment appointment = appointmentMapper.selectAppointmentById(appointmentId);
        if(appointment == null ){
            throw new ServiceException("参数异常");
        }
        //判断结算单是否生成--查询结算单上面的appintmentId 条件, 如果有值, 说明已经创建了
        Statement statement = statementMapper.selectByAppointmentId(appointmentId);
        if(statement == null){
            statement = new Statement();
            BeanUtils.copyProperties(appointment,statement);
            statement.setId(null);
            statement.setStatus(Statement.STATUS_CONSUME);
            statement.setAppointmentId(appointmentId);
            statementMapper.insertStatement(statement);

            appointment.setStatus(Appointment.STATUS_SETTLE);
            //如果没生成, 创建, 保存, 再返回id
            appointmentMapper.updateAppointment(appointment);
        }

        //如果生成, 返回id
        return statement.getId();
    }
}
